<template>
    <div class="break-ball">
        <canvas id="breakBall" width="900" height="600"></canvas>
        <div class="container" v-if="gameOver">
            <div class="dialog">
                <p class="once-again">本轮分数：{{score}}分</p>
                <p class="once-again">真好玩！</p>
                <p class="once-again">再来一次~~</p>
                <el-button class="once-again-btn" @click="init">开始</el-button>
                <el-button type="danger" @click="back_home">退出</el-button>
            </div>
        </div>
    </div>
</template>

<script>

    const randomColor = [
        "#d41313",
        "#e3b200",
        "#e35b00",
        "#00d254",
        "#002ed2",
        "#87c2b9",
        "#703caa",
        "#FFDC35",
        "#93FF93",
        "#d0d0d0"
    ];

    export default {
        name: "ball",
        data() {
            return {
                clientWidth: 0,
                clientHeight: 0,
                ctx: null,
                crushBalls: [],
                pannel: {
                    x: 0,
                    y: 0,
                    height: 8,
                    width: 100,
                    speed:7,
                    dx: 0
                },
                ball: {
                    x: 0,
                    y: 0,
                    r: 8,
                    dx: -4,
                    dy: -4
                },
                score: 0,
                gameOver: false,
                breaks: [],
                breaksConfig: {  //砖块
                    row: Math.floor((Math.random())*6+1), // 排数
                    height: 25, // 砖块高度
                    width: 130, // 砖块宽度
                    radius: 5, // 矩形圆角
                    space: 0, // 间距
                    colunm: Math.floor((Math.random())*6+1) // 列数
                }
            };
        },
        mounted(){
            let _this=this;
            let container=document.getElementById("breakBall")
            this.ctx=container.getContext("2d");
            this.clientHeight=container.height;
            this.clientWidth=container.width;
            _this.init();
            document.onkeydown = function(e) {
                let key = window.event.keyCode;
                if (key === 37  || event.keyCode==65) {
                    // 左键 或A
                    _this.pannel.dx = -_this.pannel.speed;
                } else if (key === 39  || event.keyCode==68) {
                    // 右键 或D
                    _this.pannel.dx = _this.pannel.speed;
                }
            }
            document.onkeyup=function (e) {
                _this.pannel.dx=0;
            };

            (function animloop() {
                if (!_this.gameOver) {
                    _this.movePannel();
                    _this.moveBall();
                    _this.drawAll();
                } else {
                    _this.drawCrushBreaks();
                }
                window.requestAnimationFrame(animloop);
            })();

        },
        // computed:{
        //     showBreaksCount(){
        //         return this.breaks.filter(item=>{
        //             return item.show;
        //         }).length;
        //     }
        // },

        methods:{
            init(){
                let _this = this;
                _this.gameOver = false;
                this.pannel.y = this.clientHeight - this.pannel.height;
                this.pannel.x = this.clientWidth / 2 - this.pannel.width / 2;
                this.ball.y = this.clientHeight / 2;
                this.ball.x = this.clientWidth / 2;
                this.score = 0;
                this.ball.dx = [-1,1][Math.floor(Math.random() * 2)]*4;
                this.ball.dy = [-1,1][Math.floor(Math.random() * 2)]*4;
                this.crushBalls = [];
                this.breaks = [];
                // 计算得出砖块缝隙宽度
                this.breaksConfig.space = Math.floor(
                    (this.clientWidth -
                        this.breaksConfig.width * this.breaksConfig.colunm) /
                    (this.breaksConfig.colunm + 1)
                );
                this.breaksConfig.row=Math.floor((Math.random())*6+2);
                this.breaksConfig.colunm=Math.floor((Math.random())*6+2);
                for (let i = 0; i < _this.breaksConfig.row; i++) {
                    for (let j = 0; j < _this.breaksConfig.colunm; j++) {
                        _this.breaks.push({
                            x: this.breaksConfig.space * (j + 1) + this.breaksConfig.width * j,
                            y: 10 * (i + 1) + this.breaksConfig.height * i,
                            show: true
                        });
                    }
                }
            },
            drawBall() {         //画球
                this.ctx.beginPath();
                this.ctx.arc(this.ball.x, this.ball.y, this.ball.r, 0, 2 * Math.PI);
                this.ctx.fillStyle = "#008b8b";
                this.ctx.fill();
                this.ctx.closePath();
            },
            moveBall() {
                this.ball.x += this.ball.dx;
                this.ball.y += this.ball.dy;
                this.breaksHandle();
                this.edgeHandle();
            },
            drawPanel(){
                this.drawRoundRect(this.pannel.x, this.pannel.y, this.pannel.width, this.pannel.height, 5);
                // this.ctx.fillRect(this.pannel.x,this.pannel.y,this.pannel.width,this.pannel.height);
            },
            drawRoundRect(x,y,width,height,radius){
                // this.ctx.fillRect(this.pannel.x,this.pannel.y,this.pannel.width,this.pannel.height);
                // this.ctx.fillStyle = "skyblue";
                this.ctx.beginPath()
                this.ctx.arc(x+radius,y+radius,radius,Math.PI,(Math.PI*3)/2);
                this.ctx.lineTo(width-radius+x,y)
                this.ctx.arc(
                    width-radius+x,
                    radius+y,
                    radius,
                    (Math.PI*3)/2,
                    Math.PI*2
                );
                this.ctx.lineTo(width + x, height + y - radius);
                this.ctx.arc(
                    width - radius + x,
                    height - radius + y,
                    radius,
                    0,
                    (Math.PI * 1) / 2
                );
                this.ctx.lineTo(radius + x, height + y);
                this.ctx.arc(
                    radius + x,
                    height - radius + y,
                    radius,
                    (Math.PI * 1) / 2,
                    Math.PI
                );
                this.ctx.fillStyle = "#008b8b";
                this.ctx.fill();
                this.ctx.closePath();
                // this.ctx.fillRect(180,390,55,77);
            },
            movePannel() {       //检测挡板是否在画布边缘
                this.pannel.x += this.pannel.dx;
                if (this.pannel.x > this.clientWidth - this.pannel.width) {
                    this.pannel.x = this.clientWidth - this.pannel.width;
                } else if (this.pannel.x < 0) {
                    this.pannel.x = 0;
                }
            },
            back_home(){
                this.$router.push("/home");
            },
            drawAll() {
                this.ctx.clearRect(0, 0, this.clientWidth, this.clientHeight);
                this.drawPanel();
                this.drawBall();
                this.drawScore();
                this.drawBreaks();
            },
            breaksHandle() {
                // 触碰砖块检测
                this.breaks.forEach(item => {
                    if (item.show) {
                        if (
                            this.ball.x + this.ball.r > item.x &&
                            this.ball.x - this.ball.r < item.x + this.breaksConfig.width &&
                            this.ball.y + this.ball.r > item.y &&
                            this.ball.y - this.ball.r < item.y + this.breaksConfig.height
                        ) {
                            item.show = false;
                            this.ball.dy *= -1;
                            this.score ++ ;
                            if(this.showBreaksCount === 0){
                                this.gameOver = true;
                            }
                        }
                    }
                });
            },
            edgeHandle() {
                // 边缘检测
                // 碰到顶部反弹
                if (this.ball.y - this.ball.r < 0) {
                    this.ball.dy = -this.ball.dy;
                }
                if (
                    // 碰到左右墙壁
                    this.ball.x - this.ball.r < 0 ||
                    this.ball.x + this.ball.r > this.clientWidth
                ) {
                    this.ball.dx = -this.ball.dx;
                }
                if (
                    this.ball.x >= this.pannel.x &&
                    this.ball.x <= this.pannel.x + this.pannel.width &&
                    this.ball.y + this.ball.r >= this.clientHeight - this.pannel.height
                ) {
                    // 球的x在板子范围内并触碰到了板子
                    this.ball.dy *= -1;
                } else if (
                    (this.ball.x < this.pannel.x ||
                        this.ball.x > this.pannel.x + this.pannel.width) &&
                    this.ball.y + this.ball.r >= this.clientHeight
                ) {
                    // 球碰到了底边缘了
                    this.gameOver = true;
                    this.getCurshBreaks();
                }
            },
            drawScore(){
                this.ctx.beginPath();
                this.ctx.font="14px Arial";
                this.ctx.fillStyle = "#FFF";
                this.ctx.fillText("分数："+this.score,10,this.clientHeight-14);
                this.ctx.closePath();
            },
            drawCrushBreaks() {
                this.ctx.clearRect(0, 0, this.clientWidth, this.clientHeight);
                this.crushBalls.forEach(item => {
                    this.ctx.beginPath();
                    this.ctx.arc(item.x, item.y, item.r, 0, 2 * Math.PI);
                    this.ctx.fillStyle = item.color;
                    this.ctx.fill();
                    this.ctx.closePath();
                    item.x += item.dx;
                    item.y += item.dy;
                    if (
                        // 碰到左右墙壁
                        item.x - item.r < 0 ||
                        item.x + item.r > this.clientWidth
                    ) {
                        item.dx = -item.dx;
                    }
                    if (
                        // 碰到上下墙壁
                        item.y - item.r < 0 ||
                        item.y + item.r > this.clientHeight
                    ) {
                        item.dy = -item.dy;
                    }
                });
            },
            getRandomColor() {
                return randomColor[Math.floor(Math.random() * randomColor.length)];
            },
            getRandomArbitrary(min, max) {
                return Math.random() * (max - min) + min;
            },
            getCurshBreaks() {
                let _this = this;
                this.breaks.forEach(item => {
                    if (item.show) {
                        item.show = false;
                        for (let i = 0; i < 8; i++) {
                            this.crushBalls.push({
                                x: 5,
                                y: 5,
                                dx: _this.getRandomArbitrary(-6, 6),
                                dy: _this.getRandomArbitrary(-6, 6),
                                r: _this.getRandomArbitrary(1, 4),
                                color: _this.getRandomColor()
                            });
                        }
                    }
                });
            },

            drawBreaks() {
                let _this = this;
                _this.breaks.forEach(item => {
                    if (item.show) {
                        _this.drawRoundRect(
                            item.x,
                            item.y,
                            _this.breaksConfig.width,
                            _this.breaksConfig.height,
                            _this.breaksConfig.radius
                        );
                    }
                });
            }
        },

    }

</script>

<style lang="scss" scoped>
    .break-ball {
        width: 900px;
        height: 600px;
        top: 0px;
        left: 0px;
        right: 0px;
        bottom: 0px;
        position: absolute;
        #breakBall {
            background-image: url("../assets/Game-background.jpg");
        }
        margin: auto;
        .container {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            background-color: rgba(0, 0, 0, 0.3);
            text-align: center;
            font-size: 0;
            white-space: nowrap;
            overflow: auto;
        }
        .container:after {
            content: "";
            display: inline-block;
            height: 100%;
            vertical-align: middle;
        }
        .dialog {
            width: 400px;
            height: 300px;
            background: rgba(255, 255, 255, 0.5);
            box-shadow: 3px 3px 6px 3px rgba(0, 0, 0, 0.3);
            display: inline-block;
            vertical-align: middle;
            text-align: left;
            font-size: 28px;
            color: #fff;
            font-weight: 600;
            border-radius: 10px;
            white-space: normal;
            text-align: center;
            .once-again-btn {
                background: #1f9a9a;
                border: none;
                color: #fff;
            }
        }
    }
</style>